package com.apes.framework.plugin.workflow.parser.model;

import com.apes.framework.api.SpringManager;
import com.apes.framework.util.LogicalUtil;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.model.WorkPost;
import com.apes.hr.base.repository.WorkPostRepository;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.repository.BranchRepository;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.repository.PostRepository;
import lombok.Data;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 功能：user元模型
 *
 * @author xul
 * @create 2018-06-30 14:45
 */
@Data
public class User {

    /**
     * 用户（user），岗位（post）
     */
    private String name;

    /**
     * userId、workPostId
     */
    private String id;

    /**
     * 类型：受理人（assignee），候选人（candidate）（已不使用）
     */
    private String type = "candidate";

    /**
     * 审批策略
     * name == 'role' 时：部门内审（inner），同级审（brother），越级审（super）
     * name == 'post' && id == null 时：上级（upper），越级（super）
     */
    private String strategy;

    private String remark;

    public List<Map> getUsers(String branchId, String workPostId) {
        List<Map> users = null;
        if (name.equalsIgnoreCase("user")) {
            users = new ArrayList<>();
            users.add(MapUtil.mapper("id", id));
            return users;
        } else if (name.equalsIgnoreCase("post")) {
            Branch processInitiatingDepartment = getProcessInitiatingDepartment(branchId);
            if (!StringUtils.isEmpty(id)) {
                WorkPost workPost = SpringManager.getBean(WorkPostRepository.class).findOne(id);
                if (workPost == null) throw new RuntimeException("岗位：" + id + " 配置错误！");
                users = getUsersRecursiveByBranch(processInitiatingDepartment, workPost);
            } else if (!StringUtils.isEmpty(strategy)) {
                WorkPost workPost = getTaskExecuteWorkPost(workPostId);
                workPost = workPost.getParents();
                if (workPost == null) {
                    throw new RuntimeException("审批策略：" + strategy + " 配置错误，当前任务执行人所在岗位：" + workPostId + " 没有配置上级！");
                }
                users = getUsersRecursiveByBranch(processInitiatingDepartment, workPost);
                if (users == null && strategy.equals("super")) {
                    users = getUsersRecursiveByWorkPost(processInitiatingDepartment, workPost.getParents());
                }
            }
            return users != null ? users : new ArrayList<>();
        } else {
            throw new RuntimeException("用户配置错误！");
        }
    }

    public List<Map> getUsersRecursiveByWorkPost(Branch processInitiatingDepartment, WorkPost workPost) {
        if (workPost == null) return null;
        List<Map> users = getUsersRecursiveByBranch(processInitiatingDepartment, workPost);
        if (users != null) return users;
        return getUsersRecursiveByWorkPost(processInitiatingDepartment, workPost.getParents());
    }

    private WorkPost getTaskExecuteWorkPost(String workPostId) {
        if (StringUtils.isEmpty(workPostId)) throw new RuntimeException("任务执行人岗位不允许为空！");
        WorkPost workPost = SpringManager.getBean(WorkPostRepository.class).findOne(workPostId);
        if (workPost == null) throw new RuntimeException("岗位：" + workPostId + " 配置错误！");
        return workPost;
    }

    private Branch getTaskExecuteBranch(String branchId) {
        if (StringUtils.isEmpty(branchId)) throw new RuntimeException("任务执行部门不允许为空！");
        Branch branch = SpringManager.getBean(BranchRepository.class).findOne(branchId);
        if (branch == null) throw new RuntimeException("部门：" + branchId + " 配置错误！");
        return branch;
    }

    private Branch getProcessInitiatingDepartment(String branchId){
        if (StringUtils.isEmpty(branchId)) throw new RuntimeException("流程发起部门不允许为空！");
        Branch branch = SpringManager.getBean(BranchRepository.class).findOne(branchId);
        if (branch == null) throw new RuntimeException("部门：" + branchId + " 配置错误！");
        return branch;
    }

    private Branch filterBranch(Branch branch, List<Branch> filters) {
        if (branch == null || filters == null) return null;
        if (filters.contains(branch)) return branch;
        if (LogicalUtil.in(branch.getBranchType().getCode(), "BC_sale")) {
            filters = filters.stream().filter(filter -> filter.getId().equals(branch.getId()) ||
                    LogicalUtil.notIn(filter.getBranchType().getCode(), "BC_sale")).collect(Collectors.toList());
        }
        if (branch.findBrotherAndSelf() != null) {
            for (Branch brother : branch.findBrotherAndSelf()) {
                // 筛选兄弟节点
                if (filters.contains(brother)) return brother;

                // 跳过公司节点
                if(brother.getBranchType().getCode().equals("BC_company")) continue;

                // 筛选兄弟节点的子节点
                Branch child = filterChildren(brother, filters);
                if (child != null) return child;
            }
        }
        return filterBranch(branch.getParents(), filters);
    }


    private Branch filterChildren(Branch branch, List<Branch> filters) {
        if (branch == null || filters == null) return null;
        if (branch.getChildren() != null) {
            for (Branch child : branch.getChildren()) {
                // 筛选子节点
                if (filters.contains(child)) return child;

                // 跳过公司节点
                if(child.getBranchType().getCode().equals("BC_company")) continue;

                // 筛选子节点的子节点
                Branch tempBranch = filterChildren(child, filters);
                if (tempBranch != null) return tempBranch;
            }
        }
        return null;
    }

//    /***
//     * 寻找最亲的血缘节点（未测试，弃用）
//     * @param branch
//     * @param filters
//     * @return
//     */
//    private Branch filterBloodRelationship(Branch branch, List<Branch> filters) {
//        List<Branch> referenceParents = branch.findParents();
//        Collections.reverse(referenceParents); // 倒序排列
//
//        Integer[] matchPosInt = filters.stream().map(tempBranch -> {
//            List<Branch> contrastParents = tempBranch.findParents();
//            Collections.reverse(contrastParents); // 倒序排列
//            return contrastParents;
//        }).map(contrastParents -> {
//            Branch nearestMatch_Reference = referenceParents.stream().filter(tempBranch -> {
//                Branch nearestMatch_Contrast = contrastParents.stream().filter(contrastBranch ->
//                        referenceParents.stream().anyMatch(referenceBranch ->
//                                referenceBranch.getId().equals(contrastBranch.getId()))
//                ).findFirst().orElse(null);
//                if (nearestMatch_Contrast == null) return false;
//                return nearestMatch_Contrast.getId().equals(tempBranch.getId());
//            }).findFirst().orElse(null);
//            return referenceParents.indexOf(nearestMatch_Reference);
//        }).toArray(Integer[]::new);
//
//        int[] matchPos = Arrays.stream(matchPosInt).mapToInt(Integer::valueOf).toArray();
//
//        // 获取其中最小值
//        int index = IntStream.range(0, matchPos.length).reduce((i, j) -> {
//            if( matchPos[i] == -1 && matchPos[j] == -1 ) return -1;
//            if(matchPos[i] == -1 && matchPos[j] != -1) return j;
//            if(matchPos[i] != -1 && matchPos[j] == -1) return i;
//            if(matchPos[i] != -1 && matchPos[j] != -1) return matchPos[i] >= matchPos[j] ? j : i;
//            return -1;
//        }).getAsInt();
//
//        if( index == -1 ) return null; // 说明没有匹配的数据
//
//        return filters.get(index);  // 返回最亲近的数据
//    }


    public List<Map> getUsersRecursiveByBranch(Branch processInitiatingDepartment, WorkPost workPost) {
        List<Branch> branches = SpringManager.getBean(PostRepository.class).findDistinctBranchByWorkPost(workPost);
        if (branches == null || branches.isEmpty()) return null;

        /***
         * 筛选满足条件的部门
         */
        Branch branch = filterBranch(processInitiatingDepartment, branches);
        if (branch == null) return null;

        return getUsers(branch, workPost);
    }

    private List<Map> getUsers(Branch branch, WorkPost workPost) {
        List<Post> posts = SpringManager.getBean(PostRepository.class).findAllByBranchAndWorkPost(branch, workPost);
        List<Map> users = null;
        for (Post post : posts) {
            for (com.apes.scm.rbac.model.User user : post.getAssignedUsers()) {
                if (users == null) users = new ArrayList<>();
                if (user.isDisable()) continue; // 去掉已离职的人员
                users.add(MapUtil.mapper("id", user.getId()));
            }
        }
        return users;
    }
}
